    package com.jiangtai.smartbox.service

import android.app.Service
import android.content.Intent
import android.os.Handler
import android.os.IBinder
import android.util.Log
import com.common.pos.api.util.PosUtil
import com.hjq.toast.ToastUtils
import com.jiangtai.smartbox.bean.BoxBean
import com.jiangtai.smartbox.bean.request.PersonInfoBean
import com.jiangtai.smartbox.constant.Constant
import com.jiangtai.smartbox.event.OpenBoxEvent
import com.jiangtai.smartbox.event.PutBackEvent
import com.jiangtai.smartbox.event.SearchBoxEvent
import com.jiangtai.smartbox.event.WriteBoxBean
import com.jiangtai.smartbox.util.HexUtil
import com.jiangtai.smartbox.util.Preference
import com.telpo.tps550.api.serial.Serial
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.litepal.LitePal
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.nio.charset.Charset
import java.util.*

/**
 * Created by heCunCun on 2021/6/29
 */
class MyService : Service() {

    private var mSerial: Serial? = null
    private var mOutputStream: OutputStream? = null
    private var mInputStream: InputStream? = null
    private var readThread: MyService.ReadThread? = null
    private var updateTime: Long by Preference(Constant.UPDATE_TIME, 0L)//最近盘存时间
    private var watchNum: Int by Preference(Constant.WATCH_NUM, 0)//表的数量

    private val handler = Handler()

    companion object {
        val TAG = "MyService"
        var countWatch = 0
        var countBox = 0
    }

    override fun onBind(intent: Intent?): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        EventBus.getDefault().register(this)
        initSerial()

    }

    override fun onDestroy() {
        super.onDestroy()
        EventBus.getDefault().unregister(this)
        destroySerial()
    }

    private fun sendData(data: ByteArray) { //发送命令 data
        try {
            if (mOutputStream != null) {
                mOutputStream!!.write(data)
                Log.e(TAG, "sendData = ${HexUtil.formatHexString(data, true)}")
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    private fun initSerial() {
        val ret = PosUtil.setRs485Status(0)//接收模式
        if (ret == 0) {
            Log.e(TAG, "切换接收模式成功")

        } else {
            Log.e(TAG, "切换接收模式失败")
        }
        try {
            if (mSerial == null) {
                mSerial = Serial("/dev/ttyHSL3", 115200, 0)
            }
            if (mOutputStream == null) {
                mOutputStream = mSerial!!.outputStream
            }
            if (mInputStream == null) {
                mInputStream = mSerial!!.inputStream
            }
            if (readThread == null) {
                readThread = ReadThread()
                readThread!!.start()
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }

    }

    private fun destroySerial() { //释放资源
        try {
            if (readThread != null) {
                readThread!!.interrupt()
                readThread = null
            }
            if (mOutputStream != null) {
                mOutputStream!!.close()
                mOutputStream = null
            }
            if (mInputStream != null) {
                mInputStream!!.close()
                mInputStream = null
            }
            if (mSerial != null) {
                mSerial!!.close()
                mSerial = null
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
    }


    //开柜指令
    private fun openBox(boxBean: BoxBean) {
        val ret1 = PosUtil.setRs485Status(1)//切换成发送模式
        if (ret1 == 0) {
            Log.e(TAG, "切换发送模式成功(id),boxId=${boxBean.boxId}")
// 发送开箱指令=====================================
            val bytes1 = byteArrayOf(
                0xAB.toByte(),//帧头
                0xBA.toByte(),//帧头
                boxBean.boxId.toByte(),//addr
                0x00.toByte(),//无应答
                0x00.toByte(),//无应答
                0x04.toByte(),//CMD 开柜
                0x02.toByte(),//data length
                0x00.toByte(),//data length
                0x01.toByte(),
                0xF4.toByte(),
                0xA8.toByte(),//crc
                0x71.toByte()//crc
            )
            //System.arraycopy(bytesId,0,bytes1,12,bytesId.size)
            Log.e(TAG, "crc = ${HexUtil.getCRC(bytes1.copyOfRange(2, 10))}")
            val bytesCrc = HexUtil.hexStringToByteArray(HexUtil.getCRC(bytes1.copyOfRange(2, 10)))
            bytes1[10] = bytesCrc[0]
            bytes1[11] = bytesCrc[1]
            val ret5 = PosUtil.setRs485Status(1)//切换成发送模式
            if (ret5 == 0) {
                Log.e(TAG, "切换发送模式成功(开柜)")
            }
            sendData(bytes1)
            val ret6 = PosUtil.setRs485Status(0)
            if (ret6 == 0) {
                Log.e(TAG, "切换接收模式成功(开柜)")
            }
        } else {
            Log.e(TAG, "切换发送模式失败")
        }
    }

    /**
     * 写人员信息 + 开柜
     */
    private fun openBox(boxBean: BoxBean, writeInfo: Boolean) {
        // isRunning = true
        val ret1 = PosUtil.setRs485Status(1)//切换成发送模式
        if (ret1 == 0) {
            Log.e(TAG, "切换发送模式成功(id),personId=${boxBean.personId}")
            val bytesId = HexUtil.hexStringToByteArray(boxBean.personId)
            if (writeInfo) {
                //  写ID
                val bytes3 = byteArrayOf(
                    0xAB.toByte(),//帧头
                    0xBA.toByte(),//帧头
                    boxBean.boxId.toByte(),//addr
                    0x80.toByte(),//下行反馈  锁状态
                    0x00.toByte(),//下行反馈  锁状态
                    0x03.toByte(),//CMD 传输数据
                    0x14.toByte(),//DATA LENGTH
                    0x00.toByte(),//DATA LENGTH
                    0xAA.toByte(),//DATA 开始
                    0x06.toByte(),
                    0x02.toByte(),
                    0x10.toByte(),
                    0x77.toByte(),//id开始
                    0x75.toByte(),
                    0x79.toByte(),
                    0x61.toByte(),
                    0x6E.toByte(),
                    0x77.toByte(),
                    0x65.toByte(),
                    0x69.toByte(),
                    0xA1.toByte(),
                    0xA2.toByte(),
                    0xA3.toByte(),
                    0xA4.toByte(),
                    0xA5.toByte(),
                    0xA6.toByte(),
                    0xA7.toByte(),
                    0xA8.toByte(),//id结束
                    0x2D.toByte(),//crc
                    0xA8.toByte()//crc
                )
                System.arraycopy(bytesId, 0, bytes3, 12, bytesId.size)
                Log.e(TAG, "crc = ${HexUtil.getCRC(bytes3.copyOfRange(2, 28))}")
                val bytesCrc3 =
                    HexUtil.hexStringToByteArray(HexUtil.getCRC(bytes3.copyOfRange(2, 28)))
                bytes3[28] = bytesCrc3[0]
                bytes3[29] = bytesCrc3[1]
                sendData(bytes3)
                val ret2 = PosUtil.setRs485Status(0)//切换成接收模式
                if (ret2 == 0) {
                    Log.e(TAG, "切换接收模式成功(id)")
                }
                //发送 人名===============================================================

                val bytesName = boxBean.personName.toByteArray(Charset.forName("gb2312"))
                //  val bytesName2 = "程飞麟".toByteArray(Charset.forName("gb2312"))
                //     Log.e("sb","size =${bytesName.size}, ===${HexUtil.formatHexString(bytesName)}")
                //  Log.e("sb","size =${bytesName2.size}, ===${HexUtil.formatHexString(bytesName2)}")
                val bytes2 = byteArrayOf(
                    0xAB.toByte(),//帧头
                    0xBA.toByte(),//帧头
                    boxBean.boxId.toByte(),//addr
                    0x80.toByte(),//下行反馈  锁状态
                    0x00.toByte(),//下行反馈  锁状态
                    0x03.toByte(),//CMD  传输数据
                    0x0F.toByte(),//DATA LENGTH
                    0x00.toByte(),//DATA LENGTH
                    0xAA.toByte(),
                    0x06.toByte(),
                    0x01.toByte(),
                    0x06.toByte(),
                    0x20.toByte(),//人名
                    0x20.toByte(),
                    0x20.toByte(),
                    0x20.toByte(),
                    0x20.toByte(),
                    0x20.toByte(),
                    0x20.toByte(),
                    0x20.toByte(),
                    0x20.toByte(),
                    0x20.toByte(),
                    0x20.toByte(),//人名
                    0x1A.toByte(),//crc
                    0xB6.toByte()//crc
                )
                System.arraycopy(bytesName, 0, bytes2, 12, bytesName.size)
                Log.e(TAG, "crc = ${HexUtil.getCRC(bytes2.copyOfRange(2, 23))}")
                val bytesCrc2 =
                    HexUtil.hexStringToByteArray(HexUtil.getCRC(bytes2.copyOfRange(2, 23)))
                bytes2[23] = bytesCrc2[0]
                bytes2[24] = bytesCrc2[1]
                handler.postDelayed(Runnable {
                    val ret3 = PosUtil.setRs485Status(1)//切换成发送模式
                    if (ret3 == 0) {
                        Log.e(TAG, "切换发送模式成功(人名)")
                    }
                    sendData(bytes2)
                    val ret4 = PosUtil.setRs485Status(0)//切换成接收模式
                    if (ret4 == 0) {
                        Log.e(TAG, "切换接收模式成功(人名)")
                    }
                }, 500)
            }
// 发送开箱指令=====================================
            val bytes1 = byteArrayOf(
                0xAB.toByte(),//帧头
                0xBA.toByte(),//帧头
                boxBean.boxId.toByte(),//addr
                0x00.toByte(),//无应答
                0x00.toByte(),//无应答
                0x04.toByte(),//CMD 开柜
                0x02.toByte(),//data length
                0x00.toByte(),//data length
                0x01.toByte(),
                0xF4.toByte(),
                0xA8.toByte(),//crc
                0x71.toByte()//crc
            )
            //System.arraycopy(bytesId,0,bytes1,12,bytesId.size)
            Log.e(TAG, "crc = ${HexUtil.getCRC(bytes1.copyOfRange(2, 10))}")
            val bytesCrc = HexUtil.hexStringToByteArray(HexUtil.getCRC(bytes1.copyOfRange(2, 10)))
            bytes1[10] = bytesCrc[0]
            bytes1[11] = bytesCrc[1]
            handler.postDelayed(Runnable {
                val ret5 = PosUtil.setRs485Status(1)//切换成发送模式
                if (ret5 == 0) {
                    Log.e(TAG, "切换发送模式成功(开柜)")
                }
                sendData(bytes1)
                val ret6 = PosUtil.setRs485Status(0)
                if (ret6 == 0) {
                    Log.e(TAG, "切换接收模式成功(开柜)")
                }
                // isRunning=false
            }, 1000)

        } else {
            Log.e(TAG, "切换发送模式失败")
        }
    }


    /**
     * 搜索柜子表的数量
     */
    private fun searchWatch(boxBean: BoxBean) {
        val ret = PosUtil.setRs485Status(1)//切换成发送模式
        if (ret == 0) {
            Log.e(TAG, "切换发送模式成功(查柜表状态),boxBeanId=${boxBean.boxId}")
        } else {
            Log.e(TAG, "切换发送模式失败,personId=${boxBean.boxId}")
        }
        val bytes1 = byteArrayOf(
            0xAB.toByte(),//帧头
            0xBA.toByte(),//帧头
            boxBean.boxId.toByte(),//addr
            0x08.toByte(),//无应答
            0x00.toByte(),//无应答
            0x03.toByte(),//CMD 任意
            0x04.toByte(),//data length
            0x00.toByte(),//data length
            0xAA.toByte(),
            0x00.toByte(),
            0X12.toByte(),
            0X34.toByte(),
            0xA8.toByte(),//crc
            0x71.toByte()//crc
        )
        Log.e(TAG, "crc = ${HexUtil.getCRC(bytes1.copyOfRange(2, 12))}")
        val bytesCrc = HexUtil.hexStringToByteArray(HexUtil.getCRC(bytes1.copyOfRange(2, 12)))
        bytes1[12] = bytesCrc[0]
        bytes1[13] = bytesCrc[1]
        sendData(bytes1)
        val state = PosUtil.setRs485Status(0)
        if (state == 0) {
            Log.e("sb", "切换接收模式成功")
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun searchBoxWatch(e: SearchBoxEvent) {
        //差柜子的腕表是否存在
        searchWatch(e.boxBean)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun openBox(e:OpenBoxEvent){//普通开柜
        openBox(e.boxBean)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun writeBox(e:WriteBoxBean){//写信息
        openBox(e.boxBean,true)
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun putBackWatch(e:PutBackEvent){
        openBox(e.boxBean)
        //开柜指令后,查表的状态
        handler.postDelayed(Runnable {
            searchWatch(e.boxBean)
            handler.postDelayed(Runnable {
                val lists = LitePal.where("id = ?", e.boxBean.id.toString()).find(BoxBean::class.java)
                if (lists.isNotEmpty()){
                    val fixBox =  lists[0]
                    if (fixBox.empty){
                        ToastUtils.show("请将腕表连接好再关好柜门!!!")

                        putBackWatch(e)
                    }else{
                        val perList = LitePal.where("personId =?", fixBox.personId).find(PersonInfoBean::class.java)
                        if (perList.isNotEmpty()){
                            perList[0].takeState = 0 //改为已还
                            perList[0].save()
                            fixBox.personId=""
                            fixBox.personName=""
                            fixBox.save()
                            watchNum++//更新现有表数量
                        }
                        ToastUtils.show("还表成功!!!")
                    }
                }

            },1000)
        },5000)
    }

    //接收线程
    inner class ReadThread : Thread() {
        override fun run() {
            super.run()
            while (!isInterrupted) {
                var size = 0
                try {
                    var buffer: ByteArray? = ByteArray(1024)
                    if (mInputStream != null) {
                        size = mInputStream!!.read(buffer)
                    }
                    buffer = Arrays.copyOfRange(buffer, 0, size)
                    val formatHexString = HexUtil.formatHexString(buffer, true)
                    Log.e(TAG, "接收数据==$formatHexString")
                        //盘存的时候返回 两条指令  柜子   腕表
                    if (buffer.size==10){// 柜子
                        val checkIndex = buffer[2].toInt()
                        var boxId = ""
                        if (checkIndex < 10) {
                            boxId = "0$checkIndex"
                        } else {
                            boxId = "$checkIndex"
                        }
//                         if (boxId=="01"){
//                             countBox++
//                             Log.e(TAG,"盘存1号柜子回复次数=$countBox")
//                         }
//                        val boxs = LitePal.where("boxId = ?", boxId).find(BoxBean::class.java)
//                        if (boxs.isNotEmpty()) {
//                            val boxBean = boxs[0]
//                            boxBean.isChecked = true
//                            boxBean.save()
//                        }
                    }
                    if (buffer.size > 12) {
                        val indexTag1 = buffer.indexOf(0X12.toByte())
                        val indexTag2 = buffer.indexOf(0X34.toByte())
                        if (indexTag1 == indexTag2-1){
                            val index = buffer[indexTag1-8].toInt()
                            var boxId = ""
                            if (index < 10) {
                                boxId = "0$index"
                            } else {
                                boxId = "$index"
                            }
                            Log.e(TAG, "boxId = $boxId")
                            val boxs = LitePal.where("boxId = ?", boxId).find(BoxBean::class.java)
                            if (boxs.isNotEmpty()) {
                                val boxBean = boxs[0]
                                boxBean.empty = false
                                boxBean.save()
                            }
                        }

                        //有表数据返回,直接将表柜状态改成有
                        if (buffer[10] == 0X12.toByte() && buffer[11] == 0X34.toByte()) {//腕表
                            val index = buffer[2].toInt()
                            var boxId = ""
                            if (index < 10) {
                                boxId = "0$index"
                            } else {
                                boxId = "$index"
                            }
                            Log.e(TAG, "boxId = $boxId")
                            val boxs = LitePal.where("boxId = ?", boxId).find(BoxBean::class.java)
                            if (boxs.isNotEmpty()) {
                                val boxBean = boxs[0]
                                boxBean.empty = false
                                boxBean.save()
                            }
                        }
                    }

                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }
    }
}